// 中国公民身份证号码生成（GB 11643-1999）

export type ProvinceKind = 'GD' | 'OTH'

// 部分行政区划代码（示例/常用）；真实项目可扩展或从配置加载
const REGION_CODES_GD = [
  '440100', // 广州市
  '440300', // 深圳市
  '440600', // 佛山市
  '441900', // 东莞市
  '442000', // 中山市
  '440400', // 珠海市
  '440500', // 汕头市
  '440700', // 江门市
]

const REGION_CODES_OTH = [
  '110100', // 北京市市辖区
  '310100', // 上海市市辖区
  '320100', // 南京市
  '330100', // 杭州市
  '350100', // 福州市
  '370100', // 济南市
  '410100', // 郑州市
  '420100', // 武汉市
  '430100', // 长沙市
  '500100', // 重庆市市辖区
]

// 加权因子与校验码映射
const WEIGHTS = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
const CHECK_MAP = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']

function randomInt(min: number, max: number): number {
  return Math.floor(Math.random() * (max - min + 1)) + min
}

function pick<T>(arr: T[]): T { return arr[Math.floor(Math.random() * arr.length)] }

/** 生成 YYYYMMDD 出生日期，默认 1970-2002 合理区间 */
function generateBirthday(): string {
  const year = randomInt(1970, 2002)
  const month = randomInt(1, 12)
  const dayMax = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month - 1]
  const day = randomInt(1, dayMax)
  const y = String(year)
  const m = String(month).padStart(2, '0')
  const d = String(day).padStart(2, '0')
  return `${y}${m}${d}`
}

/** 计算校验位 */
function calcCheckCode(first17: string): string {
  let sum = 0
  for (let i = 0; i < 17; i++)
    sum += Number(first17[i]) * WEIGHTS[i]
  const mod = sum % 11
  return CHECK_MAP[mod]
}

/**
 * 生成18位身份证
 * @param provinceKind GD(广东) 或 OTH(其他省)
 */
export function generateChinaId(provinceKind: ProvinceKind): string {
  const region = provinceKind === 'GD' ? pick(REGION_CODES_GD) : pick(REGION_CODES_OTH)
  const birthday = generateBirthday()
  const sequence = String(randomInt(1, 999)).padStart(3, '0')
  const first17 = `${region}${birthday}${sequence}`
  const check = calcCheckCode(first17)
  return `${first17}${check}`
}
